package com.shortlink.common.interceptor;


import cn.hutool.core.util.StrUtil;
import com.shortlink.common.constants.JwtConstant;
import com.shortlink.pojos.dto.dataobject.UserInfoDO;
import com.shortlink.utils.JWTUtil;
import com.shortlink.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.concurrent.TimeUnit;

import static com.shortlink.common.constants.RedisConstant.USER_LOGIN_KEY;
import static com.shortlink.common.constants.RedisConstant.USER_LOGIN_TTL;


/**
 * 刷新token有效期，设置UserContext
 * 比LoginInterceptor早执行
 */
@Slf4j
public class RefreshTokenInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求头中的token
        String token = request.getHeader(JwtConstant.TOKEN_NAME);
        if (StrUtil.isBlank(token)) {
            return true;
        }

        // 基于TOKEN获取用户
        UserInfoDO userInfoDO = JWTUtil.parseJwtToken(token);

        if(userInfoDO ==null) return true;

        String key=String.format(USER_LOGIN_KEY,userInfoDO.getUsername());

        // 判断token是否有效
        if(!stringRedisTemplate.hasKey(key)){
            // token过期，拦截
            return true;
        }

        // 刷新过期时间
        stringRedisTemplate.expire(key,USER_LOGIN_TTL, TimeUnit.SECONDS);

        // 保存用户信息到 ThreadLocal
        UserContext.setUser(userInfoDO);

        // 放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 移除用户
        UserContext.removeUser();
    }
}
